#include <csignal>
#include <cstdio>
#include <cstdlib>
#include "app/application.hpp"
#include "core/log.hpp"
#include "utils/single_app.hpp"
#include "utils/path_tools.hpp"
#include "utils/io_tools.hpp"
#include "utils/misc_tools.hpp"
#include "utils/string_utils.hpp"
#include "version.h"

#if _WIN32
#include <clocale>
#endif

int main(int argc, const char **argv)
{
#if _WIN32
    setlocale (LC_ALL, ".65001");
#endif

    // 设置应用程序ID
    SingleAppHelper::SetAppId("d36051cf-9c32-4f5d-a21b-6b1499370ce0");
    if (SingleAppHelper::CheckRunning()) {
        fprintf(stderr, "Program Already running, pid: %u\n", SingleAppHelper::ProcessId());
        show_proccess_main_window(SingleAppHelper::ProcessId());
        return 0;
    }   

    // support default args
    std::vector<const char*> arguments;
    std::string content = ReadTextFile("cmdline.txt"_BP);

    // // fill default
    // for (int i=0; i<argc; ++i) {
    //     arguments.emplace_back(argv[i]);
    // }

    // cmdline
    arguments.emplace_back(argv[0]);

    // load default arguments
    if (!content.empty()) {
        size_t line_start = 0, line_end = content.find('\n', line_start);
        while(line_end < content.length()) {
            // patch for windows crlf line-end
            if (content[line_end-1]=='\r')
                content[line_end-1]='\0';

            content[line_end] = '\0';
            
            auto equal_sign = content.find('=', line_start);
            if (equal_sign < line_end) {
                content[equal_sign] = '\0';
                std::string key = &content[line_start];
                const char *value_repl = &content[equal_sign+1];
                
                // replace argument
                auto it = std::find_if(begin(arguments), end(arguments), [key](auto *v){ return key == v; });
                if (it == end(arguments)) {
                    // add key and value
                    arguments.emplace_back(&content[line_start]);
                    arguments.emplace_back(value_repl);
                } else if (++it != end(arguments)) {
                    *it = value_repl;
                } else {
                    arguments.emplace_back(value_repl);
                }
            }

            line_start = line_end + 1;
            line_end = content.find('\n', line_start);
        }
    }

    if (!arguments.empty() && argc > 1) {
        for (int i=1; i<argc;) {
            std::string arg = argv[i];
            if (arg[0] == '-') {
                // key
                auto it = std::find_if(begin(arguments), end(arguments), [arg](auto *v){ return v == arg; });
                if (it == end(arguments)) {
                    arguments.emplace_back(argv[i]);
                    arguments.emplace_back(argv[i+1]);
                } else if (++it != end(arguments)) {
                    *it = argv[i+1];
                } else {
                    arguments.emplace_back(argv[i+1]);
                }
                i+=2;
            } else {
                // normal value
                arguments.emplace_back(argv[i]);
                i+=1;
            }
        }
    }

    L_INFO("PiInfo SDK v%s(%s)", get_version_str(), get_git_version());

    PiInfoApp app{(int)arguments.size(), arguments.data()};

    // L_TRACE ("Trace");
    // L_DEBUG ("Debug");
    // L_INFO ("Info");
    // L_WARN ("Warning");
    // L_ERROR ("Error");

    app.run();

    return 0;
}
